package com.whosly.demo.jmh.md;

import jdk.incubator.vector.DoubleVector;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.VectorSpecies;

/**
 * @author fengyang
 * @date 2023/11/1 上午11:05
 * @see <a href="yueny09@163.com">mailTo: yueny09@163.com</a>
 */
public class FMAAction
{

    //定义SPECIES，表示Vector的类型
    private static final VectorSpecies<Double> SPECIES = DoubleVector.SPECIES_PREFERRED;
    private static int count = 500_000;

    private double[] doubleLeft = new double[count];
    private double[] doubleRight = new double[count];

    public FMAAction() {
        init();
    }

    private final void init() {
        for (Integer i = 0; i < count; i++) {
            doubleLeft[i] = i.longValue();
            doubleRight[i] = count - i.longValue();
        }
    }

    public final double normalSum() {
        double sum = 0;
        for (int i = 0; i < doubleLeft.length; i++) {
            sum += doubleLeft[i] * doubleRight[i];
        }
        return sum;
    }

    public final double vectorSum() {
        var sum = DoubleVector.zero(SPECIES);
        int i;
        int batchSize = doubleLeft.length;
        var upperBound = SPECIES.loopBound(doubleLeft.length);
        for (i = 0; i < upperBound; i += SPECIES.length()) {
            DoubleVector va = DoubleVector.fromArray(SPECIES, doubleLeft, i);
            DoubleVector vb = DoubleVector.fromArray(SPECIES, doubleRight, i);
            sum = va.fma(vb, sum);
        }
        var c = sum.reduceLanes(VectorOperators.ADD);

        double[] doubleSum = new double[count];
        for(; i < batchSize; ++i) {
            doubleSum[i] = (doubleLeft[i] + doubleRight[i]);
        }

        return c;
    }

    public static void main(String[] args)
    {
        FMAAction action = new FMAAction();

        action.vectorSum();
    }
}
